<template>
  <a-layout class="container">
    <a-layout>
      <!-- 事件配置列表 -->
      <a-layout-sider style="width: 240px;">
        <a-card
          title="事件配置列表"
          size="small"
          :style="{ width: '240px'}"
          :body-style="{ padding:0 }"
        >
          <template #extra>
            <a-link @click="addEventConfig">
              新增
            </a-link>
          </template>
          <a-list :max-height="740">
            <a-list-item
              v-for="(item,index) in eventConfigs"
              :key="index"
              :style="{
                backgroundColor: selectConfig.id === item.id ? 'rgba(7,124,200,0.2)':'#FFF'
              }"
              @click="selectEventConfig(item)"
            >
              <a-input
                v-if="editConfig.id === item.id"
                v-model="item.name"
                style="width: 180px;"
                @blur="blurEventConfig"
              />
              <template v-else>
                <span
                  :style="{
                    fontWeight: selectConfig.id === item.id ? 'bold':'',
                    color: selectConfig.id === item.id ? '#0967cc': '#000'
                  }"
                  @dblclick.stop="editEventName(item)"
                >
                  {{ item.name }}
                </span>
              </template>
              <template #actions>
                <a-popconfirm
                  content="确定删除事件配置?"
                  type="warning"
                  position="tr"
                  @ok="deleteEventConfig(item)"
                >
                  <icon-delete style="color: red;" />
                </a-popconfirm>
              </template>
            </a-list-item>
          </a-list>
        </a-card>
      </a-layout-sider>
      <a-layout-content>
        <div
          v-if="selectConfig.id"
          class="dnd-flow"
          @drop="onDrop"
        >
          <vue-flow
            v-model:nodes="nodes"
            v-model:edges="edges"
            class="vue-flow-basic-example"
            :default-zoom="1.5"
            :min-zoom="0.2"
            :max-zoom="4"
            @dragover="onDragOver"
            @dragleave="onDragLeave"
          >
            <dropzone-background
              :style="{
                backgroundColor: isDragOver ? '#e7f3ff' : 'transparent',
                transition: 'background-color 0.2s ease',
              }"
            >
              <p v-if="isDragOver">
                Drop here
              </p>
            </dropzone-background>

            <template #node-custom="nodeProps">
              <custom-node v-bind="nodeProps" />
            </template>

            <template #node-start="nodeProps">
              <node-event-start v-bind="nodeProps" />
            </template>

            <template #node-deal="nodeProps">
              <node-event-deal v-bind="nodeProps" />
            </template>

            <template #node-end="nodeProps">
              <node-event-end v-bind="nodeProps" />
            </template>

            <template #edge-custom="edgeProps">
              <custom-edge v-bind="edgeProps" />
            </template>

            <controls />
            <save-restore-controls @save="onSave" />
            <mini-map />
          </vue-flow>
          <sidebar />
        </div>
      </a-layout-content>
    </a-layout>
  </a-layout>
</template>

<script lang="ts" setup>
import { ref, defineModel, onMounted, nextTick } from 'vue';
import { VueFlow, useVueFlow, type Node, type Edge, Connection } from '@vue-flow/core';
import { Controls } from '@vue-flow/controls';
import { MiniMap } from '@vue-flow/minimap';
import { Message } from '@arco-design/web-vue';
import { EventConfigItem } from '@/components/form-design/event/type';
import shortId from 'shortid';
import NodeEventStart from '@/components/form-design/event/node/node-event-start.vue';
import NodeEventDeal from '@/components/form-design/event/node/node-event-deal.vue';
import NodeEventEnd from '@/components/form-design/event/node/node-event-end.vue';
import CustomNode from './node/custom-node.vue';
import CustomEdge from './edge/custom-edge.vue';
import DropzoneBackground from './components/drop-zone-background.vue';
import Sidebar from './components/sidebar.vue';
import SaveRestoreControls from './components/controls.vue';
import useDragAndDrop from './use_dnd';


// 表单事件配置
const eventConfigs = defineModel(
  'config',
  {
    type: Array,
    default: []
  }
);

const { addEdges, toObject, fromObject, onConnect } = useVueFlow();

const { onDragOver, onDrop, onDragLeave, isDragOver } = useDragAndDrop();

const nodes = ref<Node[]>([]);

const edges = ref<Edge[]>([]);

onConnect((params: Connection) => {
  addEdges([{ ...params, type: 'custom' }]);
});


// 事件配置相关
// const eventConfigList = ref<Array<EventConfigItem>>([]);

const editConfig = ref<EventConfigItem>({
  id: '',
  name: ''
});

const addEventConfig = () => {
  const configId = shortId.generate();
  eventConfigs.value.push({
    id: configId,
    name: `name${configId}`
  });
};

const deleteEventConfig = (config: EventConfigItem) => {
  eventConfigs.value = eventConfigs.value.filter(item => item.id !== config.id);
};

const editEventName = (config: EventConfigItem) => {
  editConfig.value = config;
};

const blurEventConfig = () => {
  editConfig.value = {
    id: '',
    name: ''
  };
};

const selectConfig = ref<EventConfigItem>({
  id: '',
  name: ''
});

const selectEventConfig = (config: EventConfigItem) => {
  console.log('selectConfig', config);
  selectConfig.value = config;
  if (selectConfig.value.configs) {
    nextTick(() => {
      fromObject(config.configs);
    });
  } else {
    fromObject({
      nodes: [],
      edges: [],
      position: [0, 0],
      zoom: 0,
      viewport: {
        x: 0,
        y: 0,
        zoom: 1
      }
    });
  }
};

const onSave = () => {
  selectConfig.value.configs = toObject();
  console.log(selectConfig.value.configs);
  Message.info('保存成功');
};

onMounted(() => {
  // TODO 默认选中第一个
});

</script>

<style lang="less">
@import '@vue-flow/core/dist/style.css';

/* import the default theme (optional) */
@import '@vue-flow/core/dist/theme-default.css';

@import '@vue-flow/controls/dist/style.css';
@import '@vue-flow/minimap/dist/style.css';
@import '@vue-flow/core/dist/theme-default.css';

.vue-flow__minimap {
  transform: scale(75%);
  transform-origin: bottom right;
}

.dnd-flow {
  flex-direction: column;
  display: flex;
  height: 100%
}

.dnd-flow aside {
  color: #fff;
  font-weight: 700;
  border-right: 1px solid #eee;
  padding: 15px 5px;
  font-size: 12px;
  background: rgba(9, 96, 189, 0.6);
  -webkit-box-shadow: 0px 5px 10px 0px rgba(0, 0, 0, .3);
  box-shadow: 0 5px 10px #0000004d
}

.dnd-flow aside .nodes > * {
  margin-bottom: 10px;
  cursor: grab;
  font-weight: 500;
  -webkit-box-shadow: 5px 5px 10px 2px rgba(0, 0, 0, .25);
  box-shadow: 5px 5px 10px 2px #00000040;
}

.dnd-flow aside .description {
  margin-bottom: 10px;
}

.dnd-flow .vue-flow-wrapper {
  flex-grow: 1;
  height: 100%;
}

@media screen and (min-width: 640px) {
  .dnd-flow {
    flex-direction: row;
  }

  .dnd-flow aside {
    min-width: 160px;
  }
}

@media screen and (max-width: 639px) {
  .dnd-flow aside .nodes {
    display: flex;
    flex-direction: row;
    gap: 5px;
  }
}

.dropzone-background {
  position: relative;
  height: 100%;
  width: 100%
}

.dropzone-background .overlay {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
  pointer-events: none;
}


.vue-flow__panel {
  background-color: #2d3748;
  padding: 10px;
  border-radius: 8px;
  box-shadow: 0 0 1px #00000080;
}

.vue-flow__panel .buttons {
  display: flex;
  gap: 8px;
}

.vue-flow__panel button {
  border: none;
  cursor: pointer;
  background-color: #4a5568;
  border-radius: 8px;
  color: #fff;
  box-shadow: 0 0 10px #0000004d;
  width: 40px;
  height: 40px;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.vue-flow__panel button:hover {
  background-color: #2563eb;
  transition: background-color .2s;
}

.vue-flow__panel button svg {
  width: 100%;
  height: 100%
}
</style>